package com.xyz.service.impl;


import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import com.xyz.dao.mapper.TemplatePlanDaoMapper;
import com.xyz.entity.mapper.EquipmentInfoMapper;
import com.xyz.entity.mapper.PlanInfoMapper;
import com.xyz.entity.mapper.TemplatePlanMapper;
import com.xyz.entity.mapper.UpkeepDbTaskMapper;
import com.xyz.entity.pojo.*;
import com.xyz.service.AsyncPlanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional(rollbackFor = Exception.class)
public class AsyncPlanServiceImpl implements AsyncPlanService {

    @Autowired
    private TemplatePlanMapper templatePlanMapper;

    @Autowired
    private PlanInfoMapper planInfoMapper;

    @Autowired
    private TemplatePlanDaoMapper templatePlanDao;

    /*
     * 异步执行计划
     * */
    @Async
    @Override
    public void insertPlanInfoByTemplate(List<EquipmentPlanTemplate> equipmentPlanTemplateList){
        for (EquipmentPlanTemplate equipmentPlanTemplate : equipmentPlanTemplateList) {
            TemplatePlan templatePlan = templatePlanMapper.selectByPrimaryKey(equipmentPlanTemplate.getTemplateId());
            if(templatePlan != null && templatePlan.getState() == 2){
                Date firstTime = templatePlan.getFirstTime();
                //modeType 1，定期循环 ；2,运行时长；3，单次执行'
                if(templatePlan.getModeType() == 1){
                    Date planEndTime = DateUtil.endOfDay(templatePlan.getPlanEndTime());
                    int businessType = templatePlan.getBusinessType();
                    int dateInterval = templatePlan.getDateInterval();
                    List<PlanInfo> planInfoList = new ArrayList<>();
                    while ((firstTime.before(planEndTime) || firstTime.equals(planEndTime))){
                        PlanInfo planInfo = new PlanInfo();
                        planInfo.setEmId(equipmentPlanTemplate.getEmId());
                        planInfo.setPlanType(1);
                        planInfo.setTemplateId(templatePlan.getId());
                        planInfo.setTemplateName(templatePlan.getTemplateName());
                        planInfo.setIsGenerate(1);
                        planInfo.setIsDelete(1);
                        planInfo.setChangeTime(firstTime);
                        planInfo.setYear(DateUtil.year(firstTime));
                        planInfo.setMonth(DateUtil.month(firstTime)+1);
                        planInfo.setDay(DateUtil.dayOfMonth(firstTime));
                        planInfoList.add(planInfo);
                        //1日保养，2周保养，3月保养
                        if(1==businessType){
                            firstTime = DateUtil.offsetDay(firstTime,dateInterval);
                        }else if(2==businessType){
                            firstTime = DateUtil.offsetWeek(firstTime,dateInterval);
                        }else if(3==businessType){
                            firstTime = DateUtil.offsetMonth(firstTime,dateInterval);
                        }
                    }
                    templatePlanDao.insertPlanInfoList(planInfoList);
                }else if(templatePlan.getModeType() == 3){
                    PlanInfo planInfo = new PlanInfo();
                    planInfo.setEmId(equipmentPlanTemplate.getEmId());
                    planInfo.setPlanType(1);
                    planInfo.setTemplateId(templatePlan.getId());
                    planInfo.setTemplateName(templatePlan.getTemplateName());
                    planInfo.setIsGenerate(1);
                    planInfo.setIsDelete(1);
                    planInfo.setChangeTime(firstTime);
                    planInfo.setYear(DateUtil.year(firstTime));
                    planInfo.setMonth(DateUtil.month(firstTime)+1);
                    planInfo.setDay(DateUtil.dayOfMonth(firstTime));
                    planInfo.setCreateTime(new Date());
                    planInfoMapper.insertSelective(planInfo);
                }
            }
        }
    }

    @Async
    @Override
    public void insertPlanInfoByPatrol(PatrolPlan patrolPlan) {
        //2，启用；4，作废
        if(patrolPlan.getState() == 2){
            insertPlanInfoByPatrolState(patrolPlan);
        }else if(patrolPlan.getState() == 4){
            deletePlanInfoByPatrolState(patrolPlan);
        }
    }

    /*
    * 生成巡检计划
    * */
    private void insertPlanInfoByPatrolState(PatrolPlan patrolPlan){
        Date firstTime = patrolPlan.getFirstTime();
        Date planEndTime = patrolPlan.getPlanEndTime();
        int businessType = patrolPlan.getBusinessType();
        int dateInterval = patrolPlan.getDateInterval();
        List<PlanInfo> planInfoList = new ArrayList<>();
        while ((firstTime.before(planEndTime) || firstTime.equals(planEndTime))){
            PlanInfo planInfo = new PlanInfo();
            planInfo.setTreeId(patrolPlan.getEmTree());
            planInfo.setEmId(0L);
            planInfo.setPlanType(2);
            planInfo.setTemplateId(patrolPlan.getId());
            planInfo.setTemplateName(patrolPlan.getPlanName());
            planInfo.setIsGenerate(1);
            planInfo.setIsDelete(1);
            planInfo.setChangeTime(firstTime);
            planInfo.setMinuteTime(firstTime);
            planInfo.setYear(DateUtil.year(firstTime));
            planInfo.setMonth(DateUtil.month(firstTime)+1);
            planInfo.setDay(DateUtil.dayOfMonth(firstTime));
            planInfoList.add(planInfo);
            //1日巡检，2周巡检，3月巡检,4例行巡检
            if(1==businessType){
                firstTime = DateUtil.offsetDay(firstTime,dateInterval);
            }else if(2==businessType){
                firstTime = DateUtil.offsetWeek(firstTime,dateInterval);
            }else if(3==businessType){
                firstTime = DateUtil.offsetMonth(firstTime,dateInterval);
            }else if(4==businessType){
                firstTime = DateUtil.offsetHour(firstTime,dateInterval);
            }
        }
       int batchSize = 300;
        if(planInfoList.size() > batchSize){
            for (int i = 0; i < planInfoList.size(); i += batchSize) {
                List<PlanInfo> sub = ListUtil.sub(planInfoList, i, Math.min(i+batchSize,planInfoList.size()));
                templatePlanDao.insertPlanInfoList(sub);
            }
        }else {
            templatePlanDao.insertPlanInfoList(planInfoList);
        }



    }

    /*
    * 删除巡检计划
    * */
    private void deletePlanInfoByPatrolState(PatrolPlan patrolPlan){
        PlanInfoExample example = new PlanInfoExample();
        PlanInfoExample.Criteria criteria = example.createCriteria();
        criteria.andPlanTypeEqualTo(2);
        criteria.andTemplateIdEqualTo(patrolPlan.getId());
        criteria.andIsGenerateEqualTo(1);
        planInfoMapper.deleteByExample(example);
    }

}
